package test05;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map; /**
 * 数字人身份管理器 - 使用静态内部类方式实现单例
 * 选择理由：
 * 1. 线程安全：由JVM保证类加载时的线程安全
 * 2. 延迟加载：只有在调用getInstance()时才会加载SingletonHolder
 * 3. 性能优秀：无锁机制，访问性能高
 * 4. 防止反射攻击：在构造器中检查实例存在性
 */
public class DigitalHumanManager implements Serializable {

    // 用户ID和数字人数据
    private String userId;
    private Map<String, Object> avatarData;
    private boolean isInitialized;
    private long initializationTime;

    // 私有构造器 - 防止外部实例化
    private DigitalHumanManager() {
        // 防止反射攻击
        if (SingletonHolder.INSTANCE != null) {
            throw new RuntimeException("单例对象已被创建，禁止通过反射实例化！");
        }
        this.avatarData = new HashMap<>();
        this.isInitialized = false;
        System.out.println("数字人管理器实例已创建 - 时间戳: " + System.currentTimeMillis());
    }

    // 静态内部类 - 实现延迟加载和线程安全
    private static class SingletonHolder {
        private static final DigitalHumanManager INSTANCE = new DigitalHumanManager();
    }

    /**
     * 全局访问点 - 获取单例实例
     */
    public static DigitalHumanManager getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 初始化数字人
     */
    public void initializeAvatar(String userId) {
        if (isInitialized) {
            System.out.println("数字人已初始化，用户ID: " + this.userId);
            return;
        }

        this.userId = userId;
        System.out.println("开始初始化数字人... 用户ID: " + userId);

        // 模拟耗时操作
        load3DModel();
        syncCloudData();

        // 设置数字人数据
        avatarData.put("model", "高级3D模型");
        avatarData.put("assets", "虚拟资产数据");
        avatarData.put("social", "社交关系数据");
        avatarData.put("appearance", "自定义外观");

        this.isInitialized = true;
        this.initializationTime = System.currentTimeMillis();

        System.out.println("数字人初始化完成 - 耗时操作模拟结束");
    }

    /**
     * 执行数字人动作
     */
    public String performAction(String action) {
        if (!isInitialized) {
            return "错误：数字人未初始化";
        }

        String result = "用户 " + userId + " 执行动作: " + action;
        System.out.println(result);

        // 记录动作历史
        avatarData.put("lastAction", action);
        avatarData.put("lastActionTime", System.currentTimeMillis());

        return result + " - 执行成功";
    }

    /**
     * 获取数字人信息
     */
    public String getAvatarInfo() {
        if (!isInitialized) {
            return "数字人未初始化";
        }

        StringBuilder info = new StringBuilder();
        info.append("=== 数字人信息 ===\n");
        info.append("用户ID: ").append(userId).append("\n");
        info.append("初始化时间: ").append(initializationTime).append("\n");
        info.append("3D模型: ").append(avatarData.get("model")).append("\n");
        info.append("虚拟资产: ").append(avatarData.get("assets")).append("\n");
        info.append("社交关系: ").append(avatarData.get("social")).append("\n");
        info.append("最后动作: ").append(avatarData.get("lastAction")).append("\n");

        return info.toString();
    }

    /**
     * 获取用户ID
     */
    public String getUserId() {
        return userId;
    }

    /**
     * 检查是否已初始化
     */
    public boolean isInitialized() {
        return isInitialized;
    }

    // 私有方法 - 模拟加载3D模型
    private void load3DModel() {
        try {
            System.out.println("加载3D模型中...");
            Thread.sleep(1000); // 模拟耗时操作
            System.out.println("3D模型加载完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    // 私有方法 - 模拟同步云端数据
    private void syncCloudData() {
        try {
            System.out.println("同步云端数据中...");
            Thread.sleep(800); // 模拟耗时操作
            System.out.println("云端数据同步完成");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 防止克隆破坏单例
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("单例对象不支持克隆");
    }

    /**
     * 防止反序列化破坏单例
     * 在反序列化时返回单例实例
     */
    private Object readResolve() {
        return SingletonHolder.INSTANCE;
    }
}
